package cn.waka.sys.admin.service;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.waka.sys.admin.dao.IRoleDao;
import cn.waka.sys.admin.object.Page;
import cn.waka.sys.admin.object.Role;

@Service
public class RoleService {

    private static final Map<String, List<String>> authNodes = new ConcurrentHashMap<String, List<String>>();
    private IRoleDao roleDao;

    private RedisService redisService;

    @Autowired
    public void setRoleDao(IRoleDao roleDao) {
        this.roleDao = roleDao;
    }

    @Autowired
    public void setRedisService(RedisService redisService) {
        this.redisService = redisService;
    }

    public Page findPage(Page p, Map<String, Object> param) {
        int start = (p.getPage() - 1) * p.getSize();
        int size = p.getSize();
        List<Role> list = roleDao.findList(param, start, size);
        int count = roleDao.findCount(param);
        p.setData(list);
        p.setCount(count);
        int totalCount = 1;
        if (count % p.getSize() > 0) {
            totalCount = (int) Math.floor(count / p.getSize());
            totalCount++;
        } else {
            totalCount = count / p.getSize();
        }
        p.setTotalPage(totalCount);
        return p;
    }


    public Role findById(int id) {
        return roleDao.findById(id);
    }

    public List<Role> findAll() {
        return roleDao.findAll();
    }

    public int saveRole(Role r) {
        int rs = 1;
        if (r.getId() > 0) {
            rs = roleDao.updateRole(r);
        } else {
            r.setCreateAt(new java.sql.Timestamp(System.currentTimeMillis()));
            rs = roleDao.insert(r);
        }
        return rs;
    }

    public List<String> findNodeByRoleId(int authId) {
        String key = "_auth_" + authId;
        boolean hasAuth = redisService.exists(key);
        List<String> list = null;
        if (!hasAuth) {
            list = roleDao.findNodeByRoleId(authId);
            authNodes.put(key, list);
            redisService.set(key, "1");
            return list;
        } else {
            list = authNodes.get(key);
            if (list == null) {
                list = roleDao.findNodeByRoleId(authId);
                authNodes.put(key, list);
            }
            return list;
        }
    }

    @PostConstruct
    public void init() {
        refreshCache();

    }

    public void refreshCache() {
        redisService.del("_auth_all");
        Set<String> list = redisService.keys("_auth_");
        String[] keys = new String[list.size()];
        list.toArray(keys);
        if (keys != null && keys.length > 0) {
            redisService.dels(keys);
        }
    }

    public void removeCacheByKey(String id) {
        String key = "_auth_" + id;
        boolean r = redisService.exists(key);
        if (r) {
            redisService.del(key);
        }
    }

    public int updateStatus(int id, String status) {
        return roleDao.updateStatus(id, status);
    }

    public int del(int id) {
        return roleDao.del(id);
    }

}
